/***************************************************************
 * Name:      HiddenFrame.h
 * Purpose:   Code for SketchUp Ruby Extension EventRelay
 * Author:    pecan Heber
 * Created:   2008/10/21
 * Copyright: pecan Heber
 * License:   GPL
 **************************************************************/
/*
	This file is part of Eventrelay, a Ruby extension for SketchUp
	Copyright (C) 2008,2009 Pecan Heber

	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public License
	as published by the Free Software Foundation; either version 2
	of the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#ifndef HiddenFrame_H
#define HiddenFrame_H


#include "windows.h"
#include "wx/frame.h"
#include "wx/dialog.h"
#include "keybinder.h"


class wxTimer;
class wxTimeSpan;
class wxDatetime;
class wxTimerEvent;

class MSW_ProcessMacro;
class RubyClassHandler;

// Hash containg Ruby ObjectVALUE and timer milliseconds
WX_DECLARE_HASH_MAP( long, long, wxIntegerHash, wxIntegerEqual, ObjectTimerHash );
WX_DECLARE_HASH_MAP( long, long, wxIntegerHash, wxIntegerEqual, WxId2MSWIdHash );
WX_DEFINE_ARRAY_LONG(ULONG, ArrayOfULONG);

// ----------------------------------------------------------------------------
class HiddenFrame : public wxFrame
// ----------------------------------------------------------------------------
{
    // Hidden frame used to intercept keystroke and mouse events

    public:

        HiddenFrame(wxWindow* parent, wxWindowID id, const wxString& title);
        ~HiddenFrame();
        void     SetProcessed(wxEvent& event, bool trueFalse);
        bool     GetProcessed(){return m_bProcessed;}
        void     SetRubyClassHandler(RubyClassHandler* pRubyClassHandler)
                  { m_pRubyClassHandler = pRubyClassHandler; }
        RubyClassHandler* GetRubyClassHandler(){return m_pRubyClassHandler;}
        void     TimerQueAdd( ULONG idIn, LONG millsecsIn);
        bool     TimerQueRemove( ULONG ObjectId);
        unsigned GetMenuIdFromPath(const wxString menuPathIn);
        int      KeyBinderConfig();
        int      LoadConfigFile(wxString fileNameIn);

        int      SendMenuActionAdd(const wxString menuPathIn);
        int      SendMenuActionRemove(const wxString menuPathIn);
        int      SendMenuActionsNow();

        //KeyDown info
        UINT    m_KeyVkCode;
        UINT    m_KeyScanCode;
        UINT    m_KeyRepeatCount;
        UINT    m_KeyFlags; //flags fromt bits 24,29,30,31

    private:

        void OnClose(wxCloseEvent&);
        void OnKeyDown(wxKeyEvent& event);
        void OnKeyUp(wxKeyEvent& event);
        //-void RMouseDown(wxMouseEvent& event);
        //-void RMouseUp(wxMouseEvent& event);
        //-void LMouseDown(wxMouseEvent& event);
        //-void LMouseUp(wxMouseEvent& event);
        //-void MMouseDown(wxMouseEvent& event);
        //-void MMouseUp(wxMouseEvent& event);
        //-void OnMenuSelected(wxCommandEvent& event);
        void OnContextMenu(wxContextMenuEvent& event);

        void OnTimer(wxTimerEvent& event);
        void TimerStart();
        void TimerStop();
        int TimerQueUpdate( long millInterval);

        void OnIdle(wxIdleEvent& event);

        wxString GetMSWndMenuLabelByID(const HMENU hMenu, const unsigned menuId);
        wxString GetMSWndMenuLabelByPosn(const HMENU hmenu, const unsigned posnIn);
        HMENU    GetMSWndMenu(const HMENU hMenu, const wxString menuLabelIn );
        int      GetMSWndMenuItemCount(const HMENU hMenuIn);

        int      RebuildHiddenMenuBar();
        int      MSWScanMenuBar(HMENU hMenu, wxMenu* pwxMenu, const wxString menuPath);
        wxString FindAppPath(const wxString& argv0, const wxString& cwd, const wxString& appVariableName);
        int      FindMenuItem(const wxMenu* pMenuIn, const wxString menuLabelIn);
        wxMenuItem* FindMenuItem(const wxMenu* pMenuIn, const int menuIdIn, wxMenu** pMenuPtrIn);
        int      MakeIdFromPath(const wxString menuLabelIn);
        wxString GetFullMenuPath(int id);

        bool m_bProcessed;
        bool m_SketchUpHandEmulation;
        //-MSW_ProcessMacro* m_pMacroRunner;
        RubyClassHandler* m_pRubyClassHandler;
        bool CommonMouseEvent(wxMouseEvent& event, unsigned typeMouseEvent);
        int GetMappedMSWidFor(const int wxmenuID)
        {
            WxId2MSWIdHash::iterator iter = m_WxId2MSWIdMap.find( wxmenuID);
            if ( iter == m_WxId2MSWIdMap.end() )
                return 0;
            return iter->second;
        }

        // Taken from SketchUp testing
        enum {
            CONSTRAIN_MODIFIER_KEY  =  16,  //0x10
            CONSTRAIN_MODIFIER_MASK =  4,   //0x04 b 0000 0100
            COPY_MODIFIER_KEY       =  17,  //0x11
            COPY_MODIFIER_MASK      =  8,   //0x08 b 0000 1000
            ALT_MODIFIER_KEY        =  18,  //0x12
            ALT_MODIFIER_MASK       =  32,  //0x20 b 0020 0000

            SHIFT_MODIFIER_MASK = CONSTRAIN_MODIFIER_MASK,
            CTRL_MODIFIER_MASK = COPY_MODIFIER_MASK
        };
        //-enum{ m_TimerResolution = 100 }; //timer resolution 100 milliseconds
        wxTimer*     m_pTimer;
        wxDateTime   m_TimeStart;
        wxDateTime   m_TimeStop;
        wxTimeSpan   m_TimeDiff;
        long         m_TimerInterval;
        ArrayOfULONG m_OnTimerPopObjects;   //Ruby objects requesting timer service
        //-wxString     m_menuPath;
        wxMenuBar*   m_pMenuBar;
        wxString     m_ExecuteFolder;
        wxString     m_UsrCmdFolder;
        wxString     m_UsrCmdFilePath;

        wxArrayString m_SendMenuActionsAry;     //Ruby menu paths to invoke
        WxId2MSWIdHash m_WxId2MSWIdMap;         // map hidden menu to MSW menu id's

        // Hash of RubyObjectVALUE and Timer milliseconds
        ObjectTimerHash m_TimerQue;

        // the array of key profiles used by this sample app
        wxKeyProfileArray m_arrOfProfiles;

    DECLARE_EVENT_TABLE()
};
// ----------------------------------------------------------------------------
class KeyBinderDialog : public wxDialog
// ----------------------------------------------------------------------------
{
public:
	wxKeyConfigPanel *m_p;

public:
    // ctor(s)
    KeyBinderDialog(wxKeyProfileArray &arr, wxWindow *parent, const wxString& title, int);
	~KeyBinderDialog();

	void OnApply( wxCommandEvent &ev );

private:
    // any class wishing to process wxWindows events must use this macro
    DECLARE_EVENT_TABLE()
};

#endif // HiddenFrame_H
